home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
cuj0696.zip
/
DWYER.ZIP
/
QFLOAT
/
QEXP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-31
|
1KB
|
68 lines
/* qexp.c */
/* exponential function check routine */
#include "qhead.h"
#include <stdio.h>
extern QELT qlog2[], qone[];
int qtanh();
int qexp( x, y )
QELT *x, *y;
{
QELT num[NQ], den[NQ], x2[NQ];
long i;
QELT sign;
/* range reduction theory: x = i + f, 0<=f<1;
* e**x = e**i * e**f
* e**i = 2**(i/log 2).
* Let i/log2 = i1 + f1, 0<=f1<1.
* Then e**i = 2**i1 * 2**f1, so
* e**x = 2**i1 * e**(log 2 * f1) * e**f.
*/
if( x[1] == 0 )
{
qmov( qone, y );
return(0);
}
qmov(x, x2);
sign = x2[0];
if( sign != 0 )
x2[0] = 0;
qifrac( x2, &i, num ); /* x = i + f */
if( i != 0 )
{
ltoq( &i, den ); /* floating point i */
qdiv( qlog2, den, den ); /* i/log 2 */
qifrac( den, &i, den ); /* i/log 2 = i1 + f1 */
qmul( qlog2, den, den ); /* log 2 * f1 */
qadd( den, num, x2 ); /* log 2 * f1 + f */
}
x2[1] -= 1; /* x/2 */
qtanh( x2, x2 ); /* tanh( x/2 ) */
qadd( x2, qone, num ); /* 1 + tanh */
qneg( x2 );
qadd( x2, qone, den ); /* 1 - tanh */
qdiv( den, num, y ); /* (1 + tanh)/(1 - tanh) */
i += y[1];
if( i > MAXEXP )
{
if( sign != 0 )
qclear(y);
else
{
printf( "qexp overflow\n" );
qinfin(y);
}
return 0;
}
y[1] = i;
if( sign != 0 )
qdiv( y, qone, y );
return 0;
}